Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PEP 724: Stricter TypeGuard #3266

Merged
merged 83 commits into from
Sep 18, 2023
Merged

Conversation

rchiodo
Copy link
Contributor

@rchiodo rchiodo commented Aug 4, 2023

This PEP modifies TypeGuard so that the negative (false return value) can allow further narrowing in type checkers. It's based on a comment here:
python/typing#1013 (comment)

Basic requirements (all PEP Types)

  • Read and followed PEP 1 & PEP 12
  • File created from the latest PEP template
  • PEP has next available number, & set in filename (pep-NNNN.rst), PR title (PEP 123: <Title of PEP>) and PEP header
  • Title clearly, accurately and concisely describes the content in 79 characters or less
  • Core dev/PEP editor listed as Author or Sponsor, and formally confirmed their approval
  • Author, Status (Draft), Type and Created headers filled out correctly
  • PEP-Delegate, Topic, Requires and Replaces headers completed if appropriate
  • Required sections included
    • Abstract (first section)
    • Copyright (last section; exact wording from template required)
  • Code is well-formatted (PEP 7/PEP 8) and is in code blocks, with the right lexer names if non-Python
  • PEP builds with no warnings, pre-commit checks pass and content displays as intended in the rendered HTML
  • Authors/sponsor added to .github/CODEOWNERS for the PEP

Standards Track requirements

  • PEP topic discussed in a suitable venue with general agreement that a PEP is appropriate
  • Suggested sections included (unless not applicable)
    • Motivation
    • Rationale
    • Specification
    • Backwards Compatibility
    • Security Implications
    • How to Teach This
    • Reference Implementation
    • Rejected Ideas
    • Open Issues
  • Python-Version set to valid (pre-beta) future Python version, if relevant
  • Any project stated in the PEP as supporting/endorsing/benefiting from the PEP formally confirmed such
  • Right before or after initial merging, PEP discussion thread created and linked to in Discussions-To and Post-History

📚 Documentation preview 📚: https://pep-previews--3266.org.readthedocs.build/pep-0724/

rchiodo and others added 26 commits August 2, 2023 14:40
Co-authored-by: Erik De Bonte <[email protected]>
Co-authored-by: Erik De Bonte <[email protected]>
Co-authored-by: Erik De Bonte <[email protected]>
Co-authored-by: Erik De Bonte <[email protected]>
Co-authored-by: Erik De Bonte <[email protected]>
Co-authored-by: Erik De Bonte <[email protected]>
Co-authored-by: Erik De Bonte <[email protected]>
@rchiodo rchiodo requested a review from a team as a code owner August 4, 2023 20:40
pep-0725.rst Outdated Show resolved Hide resolved
pep-0724.rst Outdated Show resolved Hide resolved
pep-0724.rst Outdated Show resolved Hide resolved
@JelleZijlstra
Copy link
Member

@AA-Turner you previously requested changes, please take another look.

Copy link
Member

@AA-Turner AA-Turner left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for the delay in this re-review.

A

peps/pep-0724.rst Outdated Show resolved Hide resolved
Comment on lines 54 to 72
Given a ``TypeGuard`` and a calling function like so:

.. code-block:: python

def guard(x: P) -> TypeGuard[R]: ...

def func1(val: A):
if guard(val):
reveal_type(val) # NP
else:
reveal_type(val) # NN

Each use of a ``TypeGuard`` involves five types:

* P = ``TypeGuard`` parameter type
* R = ``TypeGuard`` return type
* A = Argument type (pre-narrowed)
* NP = Narrowed type (positive)
* NN = Narrowed type (negative)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This introduction to the Specification seems a bit odd / doesn't flow very well -- you start with "Given a function" and then in the next paragraph define a series of types with no reference or connection to the previous paragraph.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm sorry but I'm not sure which parts aren't referencing each other. Did you mean the Kangaroo | Koala example? Or the reference to the different types : 'P, R, A, NP, NN'

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did the update clarify this at all?

Comment on lines 135 to 137
Intersection of types and type negation are not defined and are left up to the
type checker to decide on how to implement. Future extensions to the type
system may define this behavior though.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was initially a little confused here, as this PEP doesn't propose Intersection[] or Negate[], but then I realised you probably mean achieving an intersection by using multiple type guards -- would it be worth adding a line of disambiguation?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, it doesn't mean achieving an intersection using multiple type guards. It means that strict type guards use intersection to define what they return. The return type of a strict type guard is the intersection of the input type (A) and the return type (R). This intersection isn't defined in Python yet.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pyright has its own implementation of this intersection at the moment.

peps/pep-0724.rst Outdated Show resolved Hide resolved
peps/pep-0724.rst Outdated Show resolved Hide resolved
peps/pep-0724.rst Outdated Show resolved Hide resolved
peps/pep-0724.rst Outdated Show resolved Hide resolved
peps/pep-0724.rst Outdated Show resolved Hide resolved
@JelleZijlstra JelleZijlstra merged commit 4830660 into python:main Sep 18, 2023
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
new-pep A new draft PEP submitted for initial review
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants